﻿using J.StatusModel;
using J.StatusModel.Dto;
using J.StatusRepository.Interface;

namespace StatusService
{
    /// <summary>
    /// 房态
    /// </summary>
    public class BookingService : IBookingService
    {
        private readonly IBookingRepository bookingRepository;

        private readonly IBookingRoomRepository bookingRoomRepository;
        private readonly IOrdersRepository ordersRepository;
        private readonly IRoomTypeRepository roomTypeRepository;
        private readonly IRoomNumManageRepository roomNumManageRepository;
        private readonly IStayRepository stayRepository;
        private readonly IReserveRepository reserveRepository;
        private readonly ISettlementRepository settlementRepository;

        public BookingService(IBookingRepository bookingRepository, IBookingRoomRepository bookingRoomRepository, IOrdersRepository ordersRepository, IRoomTypeRepository roomTypeRepository, IRoomNumManageRepository roomNumManageRepository, IStayRepository stayRepository, IReserveRepository reserveRepository, ISettlementRepository settlementRepository)
        {
            this.settlementRepository = settlementRepository;
            this.reserveRepository = reserveRepository;
            this.roomNumManageRepository = roomNumManageRepository;
            this.bookingRepository = bookingRepository;
            this.bookingRoomRepository = bookingRoomRepository;
            this.ordersRepository = ordersRepository;
            this.roomTypeRepository = roomTypeRepository;
            this.roomNumManageRepository = roomNumManageRepository;
            this.stayRepository = stayRepository;
        }
        /// <summary>
        /// 办理预定(添加预定表)
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> AddBooking(BookingModel model)
        {
            //日期相减计算住了几天
            //TimeSpan ts = model.BookingEndTime - model.BookingBeginTime;
            //取相减后日期的天数就是住的天数
            //model.TimeNumber = ts.Days;
            var result = await bookingRepository.AddAsync(model);
            return result;
        }
        /// <summary>
        /// 添加预定和房型关系表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> AddBookingRoom(List<BookingRoomModel> models)
        {
            var count = 0;
            foreach (var item in models)
            {
                //找到最近添加的一条预定信息
                var bookingList = await bookingRepository.GetAllAsync();
                var Booking = bookingList.OrderByDescending(x => x.ID).FirstOrDefault();
                //关系表中的预定id等于预定表最近一条数据的id
                item.BookingId = Booking.ID;
                //添加关系表数据
                var result = await bookingRoomRepository.AddAsync(item);
                count += result;
                //添加关系的同时添加订单表
                await AddOrders(item.RoomNum, item.Townhouse, item.RoomTypeId, item.BookingId);
                //修改房号状态为预定
                await UpdBookingState(models);
            }
            return count;
        }
        /// <summary>
        /// 添加订单表
        /// </summary>
        /// <param name="roomNum">房间数量</param>
        /// <param name="Townhouse">排房</param>
        /// <param name="RoomTypeId">房型id</param>
        /// <param name="BookingId">预定表id</param>
        /// <returns></returns>
        public async Task<int> AddOrders(int roomNum, string Townhouse, int RoomTypeId, int BookingId)
        {
            //定义计数器
            var count = 0;
            List<string> roomIds = new List<string>();
            if (Townhouse != "")
            {
                var ids = Townhouse.Split(',');
                foreach (var id in ids)
                {
                    roomIds.Add(id);
                }
            }
            //当房号数量小于房间数量时
            if (roomIds.Count() < roomNum || Townhouse == "")
            {
                var a = roomNum - roomIds.Count();
                //添加未安排房号的订单
                //房号数量小于房间数量时说明有的房间未排房，那么循环未排房的房间数量，他们的房号就是0(前台就会显示未排房)
                for (var i = 0; i < a; i++)
                {
                    //实例化一个订单表类
                    OrdersModel model = new OrdersModel();
                    model.RoomNum = 0;
                    //找到所有房型信息
                    var roomTypeList = await roomTypeRepository.GetAllAsync();
                    //找到指定的房型信息
                    var roomTypeModel = roomTypeList.Where(x => x.ID == RoomTypeId).FirstOrDefault();
                    //给订单表的房型赋值
                    model.RoomType = roomTypeModel.RoomTypeName;
                    //订单表的预定表id等于关系表的预定表id
                    model.BookingId = BookingId;
                    //给实例化的类添加OrderState状态(默认待入住，当添加入住人信息时变为已入住)
                    model.OrderState = OrderState.待入住;
                    //添加订单表
                    var result = await ordersRepository.AddAsync(model);
                    count += result;
                }
                //添加安排房号的订单
                foreach (var item in roomIds)
                {
                    //实例化一个订单表类
                    OrdersModel model = new OrdersModel();
                    model.RoomNum = Convert.ToInt32(item);
                    //找到所有房型信息
                    var roomTypeList = await roomTypeRepository.GetAllAsync();
                    //找到指定的房型信息
                    var roomTypeModel = roomTypeList.Where(x => x.ID == RoomTypeId).FirstOrDefault();
                    //给订单表的房型赋值
                    model.RoomType = roomTypeModel.RoomTypeName;
                    //订单表的预定表id等于关系表的预定表id
                    model.BookingId = BookingId;
                    //给实例化的类添加OrderState状态(默认待入住，当添加入住人信息时变为已入住)
                    model.OrderState = OrderState.待入住;
                    //添加订单表
                    var result = await ordersRepository.AddAsync(model);
                    count += result;
                }
                return count;
            }
            else
            {
                var counts = 0;
                //当房间数量等于安排的房号的个数时
                foreach (var item in roomIds)
                {
                    //实例化一个订单表类
                    OrdersModel model = new OrdersModel();
                    model.RoomNum = Convert.ToInt32(item);
                    //找到所有房型信息
                    var roomTypeList = await roomTypeRepository.GetAllAsync();
                    //找到指定的房型信息
                    var roomTypeModel = roomTypeList.Where(x => x.ID == RoomTypeId).FirstOrDefault();
                    //给订单表的房型赋值
                    model.RoomType = roomTypeModel.RoomTypeName;
                    //订单表的预定表id等于关系表的预定表id
                    model.BookingId = BookingId;
                    //给实例化的类添加OrderState状态(默认待入住，当添加入住人信息时变为已入住)
                    model.OrderState = OrderState.待入住;
                    //添加订单表
                    var result = await ordersRepository.AddAsync(model);
                    counts += result;
                }
                return counts;
            }
        }
        //public async Task<int> AddOrders(int roomNum, string Townhouse, int RoomTypeId, int BookingId)
        //{
        //    var count = 0;
        //    var roomIds = Townhouse.Split(',');

        //    for (var i = 0; i < roomNum; i++)
        //    {
        //        OrdersModel model = new OrdersModel();

        //        if (i < roomIds.Count()||Townhouse=="")
        //        {
        //            model.RoomNum = Convert.ToInt32(roomIds[i]);
        //        }
        //        else
        //        {
        //            model.RoomNum = 0;
        //        }

        //        var roomTypeModel = (await roomTypeRepository.GetAllAsync()).FirstOrDefault(x => x.ID == RoomTypeId);
        //        model.RoomType = roomTypeModel.RoomTypeName;
        //        model.BookingId = BookingId;
        //        model.OrderState = OrderState.待入住;

        //        count += await ordersRepository.AddAsync(model);
        //    }

        //    return count;
        //}
        /// <summary>
        /// (房态页面)办理入住
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> AddStay(StayModel model)
        {
            var a = await ordersRepository.GetAllAsync();
            var orderlist = a.Where(x => x.RoomNum == model.RoomNum & x.OrderState == OrderState.待入住).OrderByDescending(x => x.ID).FirstOrDefault();
            model.OrdersId = orderlist.ID;
            var result = await stayRepository.AddAsync(model);
            //修改订单状态为已入住
            orderlist.OrderState = OrderState.入住中;
            await ordersRepository.UpdateAsync(orderlist);

            //当办理入住时把房号状态修改为入住中
            var list = await roomNumManageRepository.GetAllAsync(x => x.RoomNumber == model.RoomNum);
            var NumList = list.FirstOrDefault();
            NumList.RoomState = RoomState.在住;
            await roomNumManageRepository.UpdateAsync(NumList);

            return result;
        }
        /// <summary>
        /// 取消排房
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <param name="roomNum">房号</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> CancelTownhouse(int orderId, int roomNum)
        {
            //修改该房号的状态为空房
            var list = await roomNumManageRepository.GetAllAsync(x => x.RoomNumber == roomNum);
            var roomList = list.FirstOrDefault();
            roomList.RoomState = RoomState.空房;
            var b = await roomNumManageRepository.UpdateAsync(roomList);
            //修改订单房号为0
            var orderList = await ordersRepository.GetModelAsync(orderId);
            orderList.RoomNum = 0;
            var a = await ordersRepository.UpdateAsync(orderList);
            return a + b;
        }
        /// <summary>
        /// 根据房号找到该房号最近的订单
        /// </summary>
        /// <param name="roomNum"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<StayDto> GetStayDto(int roomNum)
        {
            var list = (from a in await ordersRepository.GetAllAsync()
                        join b in await bookingRepository.GetAllAsync() on a.BookingId equals b.ID
                        where a.RoomNum == roomNum && a.OrderState == OrderState.待入住
                        select new StayDto
                        {
                            OrderId = a.ID,
                            RoomNum = a.RoomNum,
                            RoomType = a.RoomType,
                            BookingName = b.BookingName,
                            BookingPhone = b.BookingPhone,
                        }).OrderByDescending(x => x.OrderId).FirstOrDefault();
            return list;
        }

        /// <summary>
        /// 办理维修
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        public async Task<int> TransactionMaintain(int Id, RoomStates state)
        {
            var result = await roomNumManageRepository.GetModelAsync(Id);
            result.RoomStates = state;
            return await roomNumManageRepository.UpdateAsync(result);
        }
        /// <summary>
        /// 办理脏房
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        public async Task<int> TransactionPigsty(int Id, RoomStates state)
        {
            var result = await roomNumManageRepository.GetModelAsync(Id);
            result.RoomStates = state;
            return await roomNumManageRepository.UpdateAsync(result);
        }

        /// <summary>
        /// 办理保留
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public async Task<int> TransactionRetain(int Id, RoomState state, int roomNumber, ReserveModel? info)
        {
            var list = await roomNumManageRepository.GetModelAsync(Id);
            //if (RoomStates.维修 == list.RoomStates)
            //{
            //    return -1;
            //}
            //else if (RoomStates.脏房 == list.RoomStates)
            //{
            //    return -1;
            //}
            if (list.RoomNumber == roomNumber)
            {
                var result = await reserveRepository.GetAllAsync();
                var n = result.Where(x => x.RoomNumber == roomNumber).FirstOrDefault();
                if (list.RoomState == RoomState.保留)
                {
                    list.RoomState = state;
                    await roomNumManageRepository.UpdateAsync(list);
                }
                return await reserveRepository.DeleteAsync(n.ID);
            }

            await reserveRepository.AddAsync(info);
            list.RoomState = state;
            await roomNumManageRepository.UpdateAsync(list);
            return 1;
        }
        /// <summary>
        /// 所有保留
        /// </summary>
        /// <returns></returns>
        public async Task<List<ReserveModel>> RetainShowAll()
        {
            var ReserveList = await reserveRepository.GetAllAsync();
            var RoomList = await roomNumManageRepository.GetAllAsync();

            var list = from a in ReserveList
                       join b in RoomList on a.RoomNumber equals b.RoomNumber
                       group a by a.RoomNumber into g
                       select g.OrderByDescending(x => x.ID);

            return list.SelectMany(g => g).ToList();
        }


        /// <summary>
        /// 返回办理排房下的房号下拉框
        /// </summary>
        /// <param name="roomNum">房号</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<RoomNumManage>> GetRoomNum(int roomTypeId)
        {
            var room = await roomNumManageRepository.GetAllAsync(x => x.RoomId == roomTypeId && x.RoomState == RoomState.空房);
            return room;
        }
        /// <summary>
        /// 办理排房
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <param name="roomNum">房号</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> TransactRoom(int orderId, int roomNum)
        {
            var orderList = await ordersRepository.GetModelAsync(orderId);
            orderList.RoomNum = roomNum;
            var a = await ordersRepository.UpdateAsync(orderList);

            var list = await roomNumManageRepository.GetAllAsync(x => x.RoomNumber == roomNum);
            var NumList = list.FirstOrDefault();
            NumList.RoomState = RoomState.预定;
            var b = await roomNumManageRepository.UpdateAsync(NumList);
            return a + b;
        }
        /// <summary>
        /// 办理退房修改原房号的状态为空房,修改原房号的订单的房号为新房号，修改新房号的状态为入住中
        /// </summary>
        /// <param name="roomNumber">房号</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> UpdateRoomState(int roomStareNumber, int roomEndNumber)
        {
            //修改原房号的状态为空房
            var roomNumList = await roomNumManageRepository.GetAllAsync(x => x.RoomNumber == roomStareNumber);
            var roomList = roomNumList.FirstOrDefault();
            roomList.RoomState = RoomState.空房;
            var a = await roomNumManageRepository.UpdateAsync(roomList);
            //修改原房号的订单的房号为新房号
            var orderList = await ordersRepository.GetAllAsync(x => x.RoomNum == roomStareNumber && x.OrderState == OrderState.入住中);
            var ordersList = orderList.OrderByDescending(x => x.ID).FirstOrDefault();
            ordersList.RoomNum = roomEndNumber;
            var b = await ordersRepository.UpdateAsync(ordersList);
            //修改新房号的状态为入住中
            var newroomList = await roomNumManageRepository.GetAllAsync(x => x.RoomNumber == roomEndNumber);
            var newroomsList = newroomList.FirstOrDefault();
            newroomsList.RoomState = RoomState.在住;
            var c = await roomNumManageRepository.UpdateAsync(newroomsList);
            return a + b + c;
        }

        /// <summary>
        /// 预定的时候修改房态
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> UpdBookingState(List<BookingRoomModel> model)
        {

            foreach (var item in model)
            {
                //var ids = item.Townhouse.Split(',');

                List<string> ids = new List<string>();
                if (item.Townhouse != "")
                {
                    var idss = item.Townhouse.Split(',');
                    foreach (var id in idss)
                    {
                        ids.Add(id);
                    }
                }

                for (var i = 0; i < ids.Count(); i++)
                {
                    var list = await roomNumManageRepository.GetAllAsync();
                    var NumList = list.Where(x => x.RoomNumber == Convert.ToInt32(ids[i]));
                    foreach (var a in NumList)
                    {
                        a.RoomState = RoomState.预定;
                        await roomNumManageRepository.UpdateAsync(a);
                    }
                }
            }
            return 1;
        }
        /// <summary>
        /// 取消预订
        /// </summary>
        /// <param name="ordersId">订单id</param>
        /// <param name="roomNum">房号</param>
        /// <returns></returns>
        public async Task<int> UpdCancel(int roomNum)
        {
            var list = await ordersRepository.GetAllAsync(x => x.RoomNum == roomNum && x.OrderState == OrderState.待入住);
            var orderList = list.FirstOrDefault();
            orderList.OrderState = OrderState.已取消;
            var result = await ordersRepository.UpdateAsync(orderList);

            if (roomNum != 0)
            {
                var a = await roomNumManageRepository.GetAllAsync();
                var numList = a.Where(x => x.RoomNumber == roomNum).FirstOrDefault();
                numList.RoomState = RoomState.空房;
                await roomNumManageRepository.UpdateAsync(numList);
            }
            return result;
        }

        /// <summary>
        /// 退房(修改房号状态为已退房)
        /// </summary>
        /// <param name="roomNum"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> UpdReturnState(int roomNum)
        {
            var list = await roomNumManageRepository.GetAllAsync();
            var NumList = list.Where(x => x.RoomNumber == roomNum).FirstOrDefault();
            var orderList = await ordersRepository.GetAllAsync(x => x.OrderState == OrderState.入住中 && x.RoomNum == roomNum);
            var list2 = orderList.FirstOrDefault();
            NumList.RoomState = RoomState.空房;
            NumList.RoomStates = RoomStates.脏房;
            list2.OrderState = OrderState.已退房;
            var result1 = await ordersRepository.UpdateAsync(list2);
            var result = await roomNumManageRepository.UpdateAsync(NumList);
            return result + result1;
        }
        /// <summary>
        /// 显示在住和预订人信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<List<SlotDto>> SlotDtoShow(RoomState state)
        {
            var RoomList = await roomNumManageRepository.GetAllAsync();
            var OrderList = await ordersRepository.GetAllAsync();

            var BookList = await bookingRepository.GetAllAsync();
            var RelationList = await bookingRoomRepository.GetAllAsync();
            var StayList = await stayRepository.GetAllAsync();


            if (RoomState.预定 == state)
            {
                var list = from a in OrderList
                           join b in BookList on a.BookingId equals b.ID
                           join c in RelationList on b.ID equals c.BookingId
                           join e in RoomList on a.RoomNum equals e.RoomNumber
                           where e.RoomState == state
                           select new SlotDto
                           {
                               Name = b.BookingName,
                               Phone = b.BookingPhone,
                               BeginTime = b.BookingBeginTime,
                               EndTime = b.BookingEndTime,
                               TimeNumber = b.TimeNumber,
                               roomState = e.RoomState,
                               orderState = a.OrderState,
                               roomNumber = e.RoomNumber,
                               customizePrice=c.CustomizePrice
                           };
                return list.ToList();
            }
            else if (RoomState.在住 == state)
            {
                var list = from a in OrderList
                           join b in BookList on a.BookingId equals b.ID
                           join c in RelationList on b.ID equals c.BookingId
                           join d in StayList on a.ID equals d.OrdersId
                           join e in RoomList on a.RoomNum equals e.RoomNumber
                           where e.RoomState == state
                           select new SlotDto
                           {
                               Name2 = d.RoomName,
                               Phone2 = d.Phone,
                               BeginTime = b.BookingBeginTime,
                               EndTime = b.BookingEndTime,
                               TimeNumber = b.TimeNumber,
                               roomState = e.RoomState,
                               orderState = a.OrderState,
                               roomNumber = e.RoomNumber,
                               customizePrice = c.CustomizePrice
                           };
                return list.ToList();
            }

            var allData = from a in OrderList
                          join b in BookList on a.BookingId equals b.ID
                          join c in RelationList on b.ID equals c.BookingId
                          join e in RoomList on a.RoomNum equals e.RoomNumber
                          select new SlotDto
                          {
                              Name = b.BookingName,
                              Name2 = b.BookingName,
                              Phone = b.BookingPhone,
                              Phone2 = b.BookingPhone,
                              BeginTime = b.BookingBeginTime,
                              EndTime = b.BookingEndTime,
                              TimeNumber = b.TimeNumber,
                              roomState = e.RoomState,
                              orderState = a.OrderState,
                              roomNumber = e.RoomNumber,
                              customizePrice = c.CustomizePrice
                          };
            return allData.ToList();
        }
        /// <summary>
        /// 返回某房间的自定义价格
        /// </summary>
        /// <param name="roomNumber"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<object> GetPrice(int roomNumber)
        {
            var list = from a in await bookingRepository.GetAllAsync()
                       join b in await bookingRoomRepository.GetAllAsync() on a.ID equals b.BookingId
                       join c in await ordersRepository.GetAllAsync() on a.ID equals c.BookingId
                       where c.RoomNum == roomNumber && c.OrderState == OrderState.入住中
                       select b.CustomizePrice;
            return list;
        }
        /// <summary>
        /// 办理结算
        /// </summary>
        /// <param name="Id">编号</param>
        /// <param name="info">结算表信息</param>
        /// <returns></returns>
        public async Task<int> HandleSettlement(int Id, SettlementModel? info)
        {
            var list = await roomNumManageRepository.GetModelAsync(Id);

            if (list.RoomState == RoomState.在住)
            {
                SettlementModel settlementInfo = new SettlementModel
                {
                    Business = 3,
                    SettlementTime = DateTime.Now,
                    AccountStatus = OrderState.已结算,
                    Astract = "111",
                    Consumption = 300,
                    Payment = 300,
                    Operator = "19897154130"
                };
                await settlementRepository.AddAsync(settlementInfo);
                list.RoomState = RoomState.空房;
                list.RoomStates = RoomStates.脏房;
                return await roomNumManageRepository.UpdateAsync(list);
            }
            else
            {
                return -1;
            }
        }
        public async Task<List<SettlementModel>> SettlementShow()
        {
            return await settlementRepository.GetAllAsync();
        }
        /// <summary>
        /// 今日预订信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<BookingModel>> BookingShow()
        {
            var list = await bookingRepository.GetAllAsync();
            list = list.Where(x => x.BookingBeginTime.Date == DateTime.Now.Date).ToList();
            return list;
        }
        /// <summary>
        /// 今日新顾客信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<BookingModel>> NewPeopleShow()
        {
            var list = await bookingRepository.GetAllAsync();
            // 执行按手机号分组操作，并选择每个分组中的第一个元素
            var distinctList = list.GroupBy(x => x.BookingPhone)
                                   .Select(g => g.First())
                                   .ToList();
            distinctList = distinctList.Where(x => x.BookingBeginTime.Date == DateTime.Now.Date).ToList();

            

            return distinctList;
        }
        /// <summary>
        /// 今日入住信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<SlotDto>> StayShow()
        {
            var StayList = await stayRepository.GetAllAsync();
            var BookList = await bookingRepository.GetAllAsync();
            var OrderList = await ordersRepository.GetAllAsync();
            var list = from a in OrderList
                       join b in BookList on a.BookingId equals b.ID
                       join c in StayList on a.ID equals c.OrdersId
                       select new SlotDto
                       {
                           Name = c.RoomName,
                           Phone2 = c.Phone,
                           BeginTime = b.BookingBeginTime,
                           EndTime = b.BookingEndTime,
                           TimeNumber = b.TimeNumber,
                           orderState = a.OrderState
                       };
            list = list.Where(x => x.BeginTime.ToString("yyyy-MM-dd") == DateTime.Now.Date.ToString("yyyy-MM-dd"));
            list = list.Where(x => x.orderState == OrderState.入住中);
            return list.ToList();
        }
        /// <summary>
        /// 今日在线预订信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<BookingModel>> OnLineBookingShow()
        {
            var list = await bookingRepository.GetAllAsync();
            list = list.Where(x => x.BookingBeginTime.Date >= DateTime.Now.Date).ToList();
            return list;
        }
    }
}
